package com.test.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @author 徒有琴
 */
@Aspect
@Component
public class DataSourceAspect {
    //@Pointcut("@annotation(com.test.aop.DS)") //只扫方法
    @Pointcut("@within(com.test.aop.DS)")//类和方法
    public void dsPointCut() {
    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        DS dataSource = method.getAnnotation(DS.class);

        if (dataSource == null) {
            Class clazz = point.getTarget().getClass();
            dataSource = (DS) clazz.getAnnotation(DS.class);
            if (dataSource == null) {
                //获取接口上的注解
                for (Class<?> cls : clazz.getInterfaces()) {
                    dataSource = cls.getAnnotation(DS.class);
                    if (dataSource != null) {
                        break;
                    }
                }
            }
        }
        if (dataSource != null) {
            DynamicDataSourceContextHolder.setDateSourceType(dataSource.value().name());
        }
        try {
            return point.proceed();
        } finally {
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.clearDateSourceType();
        }
    }
}
